package repository

import (
	"buding-ai/internal/core"
	"buding-ai/internal/repository/model"
	"buding-ai/internal/web/response"
	"buding-ai/pkg/utils/paginate"
	"buding-ai/pkg/utils/password"
	"errors"
	"sync"
	"time"
)

var (
	userRepos *UserRepository
	userOnce  sync.Once
)

type UserRepository struct {
	// 删除db字段，统一使用全局core.DB
}

func GeUserRepository() *UserRepository {
	userOnce.Do(func() {
		userRepos = &UserRepository{}
	})
	return userRepos
}

// GetByUserName 根据用户名获取用户
func (r *UserRepository) GetByUserName(username string) (*model.User, error) {
	var user model.User
	if err := core.DB.Where("username = ?", username).First(&user).Error; err != nil {
		return nil, errors.New("数据库查询出现异常:" + err.Error())
	}
	return &user, nil
}

// GetById 根据ID获取用户
func (r *UserRepository) GetById(id uint) (*model.User, error) {
	var user model.User
	if err := core.DB.First(&user, id).Error; err != nil {
		return nil, errors.New("数据库查询出现异常:" + err.Error())
	}
	return &user, nil
}

// GetByIdUint64 根据uint64类型的ID获取用户
func (r *UserRepository) GetByIdUint64(id uint64) (*model.User, error) {
	var user model.User
	if err := core.DB.First(&user, id).Error; err != nil {
		return nil, errors.New("数据库查询出现异常:" + err.Error())
	}
	return &user, nil
}

// UpdateLoginTime 更新最后登录时间
func (r *UserRepository) UpdateLoginTime(id uint) error {
	return core.DB.Model(&model.User{}).Where("id = ?", id).UpdateColumn("last_login_at", time.Now()).Error
}

// CheckUserExistsByUsername 检查用户名是否已存在
func (r *UserRepository) CheckUserExistsByUsername(username string) (bool, error) {
	var count int64
	if err := core.DB.Model(&model.User{}).Where("username = ?", username).Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}

// CheckPhoneExists 检查手机号是否已存在
func (r *UserRepository) CheckPhoneExists(phone string) (bool, error) {
	var count int64
	if err := core.DB.Model(&model.User{}).Where("phone = ?", phone).Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}

// CheckEmailExists 检查邮箱是否已存在
func (r *UserRepository) CheckEmailExists(email string) (bool, error) {
	var count int64
	if err := core.DB.Model(&model.User{}).Where("email = ?", email).Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}

// CheckPhoneExistsExcept 检查手机号是否被其他用户使用
func (r *UserRepository) CheckPhoneExistsExcept(phone string, userId uint64) (bool, error) {
	var count int64
	if err := core.DB.Model(&model.User{}).Where("phone = ? AND id != ?", phone, userId).Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}

// CheckEmailExistsExcept 检查邮箱是否被其他用户使用
func (r *UserRepository) CheckEmailExistsExcept(email string, userId uint64) (bool, error) {
	var count int64
	if err := core.DB.Model(&model.User{}).Where("email = ? AND id != ?", email, userId).Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}

// CreateUser 创建用户
func (r *UserRepository) CreateUser(user *model.User) error {
	return core.DB.Create(user).Error
}

// UpdateUser 更新用户信息
func (r *UserRepository) UpdateUser(id uint64, updates map[string]interface{}) error {
	return core.DB.Model(&model.User{}).Where("id = ?", id).Updates(updates).Error
}

// DeleteUser 删除用户
func (r *UserRepository) DeleteUser(id uint64) error {
	return core.DB.Where("id = ?", id).Delete(&model.User{}).Error
}

// GetUserPage 分页获取用户列表
func (r *UserRepository) GetUserPage(pageRequest paginate.PageRequest) (*paginate.PageResponse, error) {
	query := core.DB.Model(&model.User{})

	// 如果有搜索关键词，添加模糊查询条件
	if pageRequest.Keyword != "" {
		searchTerm := "%" + pageRequest.Keyword + "%"
		query = query.Where("username LIKE ? OR nickname LIKE ? OR phone LIKE ? OR email LIKE ?",
			searchTerm, searchTerm, searchTerm, searchTerm)
	}

	// 执行分页查询
	var users []response.UserVO
	pageResult, err := paginate.Paginator(query, pageRequest.Page, pageRequest.PageSize, pageRequest.Sort, pageRequest.Order, &users)

	if err != nil {
		return nil, err
	}

	return &pageResult, nil
}

// ResetPassword 重置用户密码
func (r *UserRepository) ResetPassword(id uint64, newPassword string) error {
	// 生成新密码和盐值
	encodedPassword, salt := password.GeneratePassword(newPassword)

	// 更新密码和盐值
	updates := map[string]interface{}{
		"password":   encodedPassword,
		"salt":       salt,
		"updated_at": time.Now(),
	}

	return core.DB.Model(&model.User{}).Where("id = ?", id).Updates(updates).Error
}
